package com.etung.iot.demo.core;

import com.etung.iot.demo.constant.CommonConstant;
import com.etung.iot.demo.modles.UserEntity;
import com.etung.iot.demo.services.UserService;
import com.etung.iot.demo.vo.req.UserAuth;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Slf4j
public class AuthAspect {

    @Autowired
    private UserService userService;

    @Pointcut("@annotation(com.etung.iot.demo.core.Authorized)")
    public void authorized() {
    }

    @Before("authorized()")
    public void doBefore(JoinPoint joinPoint) throws RuntimeException {
        String token = getToken(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
        if (StringUtils.isEmpty(token)) {
            throw new RuntimeException("认证失败！");
        }
        //生产环境下请使用redis进行token认证
        String uid = userService.retrieveUserIdFromToken(token);
        if (!StringUtils.isEmpty(uid)) {
            UserEntity userEntity = userService.selectByPrimaryKey(uid);
            if (userEntity == null) {
                throw new RuntimeException("认证失败！");
            }
        } else {
            throw new RuntimeException("认证失败！");
        }

        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if (arg instanceof UserAuth) {
                UserAuth req = (UserAuth) arg;
                req.setId(uid);
            }

        }
    }

    private String getToken(HttpServletRequest request) {
        // 从 header中获取
        return request.getHeader(CommonConstant.AUTH_TOKEN_STRING);
    }
}
